import handler.DataDecoder;
import handler.ServerHandler;
import handler.SocketMessageEncode;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

import java.nio.ByteOrder;
import java.util.logging.Logger;

/**
 * @description:
 * @author: sali
 * @date: 2025/2/16 下午2:00.
 * @version: 1.0
 */
public class NettyServer {

    private final Logger log = Logger.getLogger(NettyServer.class.getName());

    private final int port;

    public NettyServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws Exception {
        int port = 8867; // 服务端监听端口
        new NettyServer(port).run();
    }

    public void run() throws Exception {
        //创建EventLoopGroup
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        WriteBufferWaterMark writeBufferWaterMark = new WriteBufferWaterMark(512 * 1024 * 20, 1024 * 1024 * 20);
        try {
            //创建ServerBootstrap
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    //指定所使用的 NIO传输 Channel
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 2048)
                    .option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 20)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .option(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark)
                    .childOption(ChannelOption.SO_SNDBUF, 1024 * 1024 * 20)
                    .childOption(ChannelOption.TCP_NODELAY, false)
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    // 添加一个handler到ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            ch.pipeline()
                                    .addLast(
                                    new DataDecoder(ByteOrder.LITTLE_ENDIAN, 2000000000, 0, 4, 0, 0, true),
                                    new SocketMessageEncode(),
                                    new IdleStateHandler(30, 30, 90),
                                    new ServerHandler());
                        }
                    });
            // 异步地绑定服务器；调用 sync()方法阻塞 等待直到绑定完成
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            log.info("netty server running......");
            // 获取 Channel 的CloseFuture，并且阻塞当前线程直到它完成
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            log.info("server server error: " + e);
        } finally {
            // 释放资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }


}
